package org.roguelikedevelopment.dweller.j2se;

import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.roguelikedevelopment.dweller.common.application.DataStorage;
import org.roguelikedevelopment.dweller.common.application.DwellerApplication;
import org.roguelikedevelopment.dweller.common.application.DwellerCanvas;
import org.roguelikedevelopment.dweller.common.game.GameCommand;
import org.roguelikedevelopment.dweller.common.game.GameHandler;
import org.roguelikedevelopment.dweller.common.game.GameSettings;
import org.roguelikedevelopment.dweller.common.util.logger.Logger;

public class DwellerJ2SEApplication extends Frame implements DwellerApplication, WindowListener {

	private static final long serialVersionUID = 1L;
	
	private static final int WIDTH = 300;
	private static final int HEIGHT = 400;
	
	private DwellerJ2SECanvas canvas;
	private GameHandler game = null;
	private SaveFileStorage storage = null;

	public static void main(String[] args) {
		new DwellerJ2SEApplication();
	}
	
	public DwellerJ2SEApplication() {
		super("Dweller");
		storage = new SaveFileStorage();
	   	game = GameHandler.getInstance();
		canvas = new DwellerJ2SECanvas(WIDTH, HEIGHT, game);
		addWindowListener(this);
		setSize(WIDTH, HEIGHT);
		setVisible(true);
		add(canvas);
	}
	
	@Override
	public void exit() {
		System.exit(0);
	}

	@Override
	public DwellerCanvas getCanvas() {
		return canvas;
	}

	@Override
	public DataStorage getDataStorage() {
		return storage;
	}

	@Override
	public DataInputStream getFile(String name) {
		InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(name);
		BufferedInputStream bis = null;
		DataInputStream dis = null;
		try {
			bis = new BufferedInputStream(is);
			dis = new DataInputStream(bis);
		}
		catch(Exception e) {
			System.err.println(e);
		}
		return dis;
	}

	@Override
	public String getKeyCodeName(int keyCode) {
		return KeyCodeUtil.getKeyCodeName(keyCode);
	}

	@Override
	public void setDefaultKeys() {
		GameCommand.initializeCommand(GameCommand.CMD_LOOK, KeyEvent.VK_NUMPAD0, KeyEvent.VK_L, false, false);
		GameCommand.initializeCommand(GameCommand.CMD_DOWNLEFT, KeyEvent.VK_NUMPAD1, KeyEvent.VK_NUMPAD1, false, false);
		GameCommand.initializeCommand(GameCommand.CMD_DOWN, KeyEvent.VK_NUMPAD2, KeyEvent.VK_DOWN, false, true);
		GameCommand.initializeCommand(GameCommand.CMD_DOWNRIGHT, KeyEvent.VK_NUMPAD3, KeyEvent.VK_NUMPAD3, false, false);
		GameCommand.initializeCommand(GameCommand.CMD_LEFT, KeyEvent.VK_NUMPAD4, KeyEvent.VK_LEFT, false, true);
		GameCommand.initializeCommand(GameCommand.CMD_CENTER, KeyEvent.VK_NUMPAD5, KeyEvent.VK_ENTER, false, true);
		GameCommand.initializeCommand(GameCommand.CMD_RIGHT, KeyEvent.VK_NUMPAD6, KeyEvent.VK_RIGHT, false, true);
		GameCommand.initializeCommand(GameCommand.CMD_UPLEFT, KeyEvent.VK_NUMPAD7, KeyEvent.VK_NUMPAD7, false, false);
		GameCommand.initializeCommand(GameCommand.CMD_UP, KeyEvent.VK_NUMPAD8, KeyEvent.VK_UP, false, true);
		GameCommand.initializeCommand(GameCommand.CMD_UPRIGHT, KeyEvent.VK_NUMPAD9, KeyEvent.VK_NUMPAD9, false, false);
		GameCommand.initializeCommand(GameCommand.CMD_INVENTORY, KeyEvent.VK_ADD, KeyEvent.VK_I, false, false);
		GameCommand.initializeCommand(GameCommand.CMD_MENU, KeyEvent.VK_MULTIPLY, KeyEvent.VK_M, false, false);
		GameCommand.initializeCommand(GameCommand.CMD_EXIT, KeyEvent.VK_MINUS, KeyEvent.VK_ESCAPE, false, false);
		GameCommand.initializeCommand(GameCommand.CMD_CYCLETARGET, KeyEvent.VK_DECIMAL, KeyEvent.VK_TAB, false, false);
	}

	@Override
	public void settingsChanged(GameSettings settings) {
		if(settings.isUsingGraphics()) {
			canvas.loadGraphics();
		}
		else {
			canvas.loadASCII();
		}
		
		if(settings.isUsingNormalTiles()) {
			canvas.useNormalTiles();
		}
		else {
			canvas.useLargeTiles();
		}
	}

	@Override
	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosing(WindowEvent e) {
		if(game.hasUnfinishedGame()) {
			try {
				game.saveGame();
			}
			catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		System.exit(0);
	}

	@Override
	public void windowDeactivated(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowOpened(WindowEvent e) {
		canvas.initialize();
    	game.init(this);
	}
}
